package com.yj.web.interceptor;

import com.yj.passport.entity.UserPassport;
import com.yj.passport.service.PassportService;
import com.yj.web.Constants;
import com.yj.web.annotation.LoginRequired;
import com.yj.web.annotation.ResultType;
import com.yj.web.dao.po.admin.Employee;
import com.yj.web.help.RoleMap;
import com.yj.web.service.EmployeeService;
import com.yj.web.util.BaseWebResult;
import com.yj.web.util.WebErrorCode;
import com.yj.web.util.WebUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;

/**
 * 这里面的代码的顺序很重要. Employee: yesiming Date: 13-11-4 Time: 下午2:50 To change this
 * template use File | Settings | File Templates.
 */
public class LoginAnnotationInterceptor extends HandlerInterceptorAdapter {

	private static final Log logger = LogFactory.getLog(LoginAnnotationInterceptor.class);

	private static final String LOGIN_URI = "/";

    @Autowired
    private PassportService passportService;
    
    @Autowired
    private EmployeeService employeeService;

	@Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException{
        BaseWebResult result = new BaseWebResult();
		response.setCharacterEncoding("UTF-8");

		String requestURI = request.getRequestURI();
        try {

            logger.info("request.getRequestURI:" + request.getRequestURI());

            request.setAttribute("_server_time", System.currentTimeMillis());

            // 防止用户构造非登陆用户修改登录用户得信息
            request.removeAttribute("hostUser");
            request.removeAttribute("hostId");
            // 查看是否在登录状态
            long hostId = 0;
            UserPassport passport = null;
            Employee employee = null;
            //String pubTicket = WebUtils.getCookie(request, Constants.KEY_PUBTICKET_COOKIE);
            //String pubTicket = request.getParameter("t");
            String pubTicket = request.getHeader("t");
            if (!StringUtils.isEmpty(pubTicket)) {
//                hostId = passportService.getUserIdByTicket4Web(pubTicket);
                passport = passportService.getPassportByTicket4Web(pubTicket);
                if (passport != null) {
                    hostId = passport.getUserId();
                    if (logger.isDebugEnabled()) {
                        logger.debug("-------hostId " + hostId);
                    }
                    if (hostId > 0) {
                        employee = this.employeeService.findEmployeeById(hostId);
                        // TODO userService要完成
//                            employee = new Employee();

                        if (logger.isDebugEnabled()) {
                            logger.debug("-------employee " + employee);
                        }
                        if (employee != null) {
                            Set<String> views = RoleMap.VIEW_ROLE_MAP.get(employee.getRoleNumber());
                            Set<String> operations = RoleMap.OPERATION_ROLE_MAP.get(employee.getRoleNumber());
                            if ((null != views && views.contains(requestURI)) || (null != operations && operations.contains(requestURI))) {
                                request.setAttribute("hostUser", employee);
                                request.setAttribute("hostId", employee.getId());
                            } else {
                                PrintWriter out = response.getWriter();
                                BaseWebResult rt = new BaseWebResult();
                                rt.setCd(WebErrorCode.E_NO_AUTHORITY);
                                out.print(WebUtils.webResultToJSON(rt));
                                out.flush();
                                return false;
                            }
                        }

                    }
                }
            }

            if (logger.isDebugEnabled()) {
                logger.debug("-------pubTicket " + pubTicket);
            }
            HandlerMethod methodHandler = (HandlerMethod) handler;
            LoginRequired loginRequired = methodHandler.getMethod().getAnnotation(LoginRequired.class);

            if (loginRequired == null) {
                // 不需要登录
                if (passport != null) {
                    // 给客户端置入CSRFTOKEN
                    request.setAttribute(Constants.CSRF_TOKEN_CLIENT_NAME, passport.getUuid());
                }
                return true;
            }

            PrintWriter out = response.getWriter();

            // 验票
            if (StringUtils.isEmpty(pubTicket)) {
                if (loginRequired.value() == ResultType.json) {
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                } else {
//                    response.sendRedirect(LOGIN_URI);
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                }

                return false;
            }
            //登录失败
            if (hostId == 0) {
                if (loginRequired.value() == ResultType.json) {
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                } else {
//                    response.sendRedirect(LOGIN_URI);
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                }

                return false;
            }
            //登录失败
            if (employee == null) {
                if (loginRequired.value() == ResultType.json) {
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                } else {
//                    response.sendRedirect(LOGIN_URI);
                    BaseWebResult rt = new BaseWebResult();
                    rt.setCd(WebErrorCode.E_SYS_NOT_LOGGED_IN);
                    out.print(WebUtils.webResultToJSON(rt));
                    out.flush();
                }

                return false;
            }

            // TODO: 以后要加antispam的操作

            /**
             if (WebContentGenerator.METHOD_POST.equalsIgnoreCase(request.getMethod())) {
             // anti CSRF 只对post做限制
             String clientCSRFToken = request.getParameter(Constants.CSRF_TOKEN_CLIENT_NAME);
             //                if (StringUtils.isEmpty(clientCSRFToken)) {
             //                    clientCSRFToken = request.getHeader(Constants.CSRF_TOKEN_CLIENT_NAME);
             //                }
             if (StringUtils.isEmpty(clientCSRFToken)) {
             response.sendRedirect(LOGIN_URI);
             return false;
             }
             String cacheCSRFToken = passport.getUuid();
             if (!clientCSRFToken.equals(cacheCSRFToken)) {
             response.sendRedirect(LOGIN_URI);
             return false;
             }
             }
             */

            // 给客户端置入CSRFTOKEN
            request.setAttribute(Constants.CSRF_TOKEN_CLIENT_NAME, passport.getUuid());

        } catch (Exception e) {
            logger.error("LoginAnnotationInterceptor error", e);
            return false;
        }

        return true;
	}
}
